package FIT::Module::Compiler;

use strict;
use warnings;

# NOTE: changes here require clearing all **/*.p(l|m)c files in project!

my @DEFAULT_USE = qw(strict warnings Data::Dumper);

sub compile {
	my ($self, %args) = @_;
	local $_;
	my $src       = $args{src};
	my $prefix    = $args{prefix}    || '';
	my $is_script = $args{is_script} || 0;
	my @use       = @{ $args{use}    || [] };

	# copied from Spiffy: add self to subs with no () prototype
    # and no attributes
    unless ($is_script) {
        $src =~
            s[^(sub\s+\w+\s+\{)(.*\n)]
             [${1}my \$self = shift;$2]gm;
        $src =~
            s[^(sub\s+\w+)\s*\(\s*\)(\s+\{.*\n)]
             [${1}${2}]gm;
        # handle moose method modifiers
        $src =~
            s[^((?:after|before|override|augment|around)\s+(?:[\w:]+)\s+=>\s+sub\s+\{)(.*\n)]
             [${1}my \$self = shift;$2]gm;
        $src =~
            s[^(around\s+\w+\s+=>\s+sub\s+\{)(.*\n)]
             [${1}my \$next = shift;$2]gm;
    }

    # makes all "die"s of whatever reason show stack trace
    $prefix =
        'use Carp qw(verbose confess);$SIG{__DIE__}=$SIG{__WARN__}=\\&confess;'.
        $prefix;

    # prefix with 'use' lines, and suffix with a '1;'
	$src =
        "\n". # must be inserted because of an evil Module::Compile bug
		join('', map { "use $_; " } (@DEFAULT_USE, @use)).
        "$prefix;$src\n1;\n";
	return $src;
}

1;
